#include "allThread.h"
#include "comm_monitor.h"
#include "RealtimeWaveform.h"
#include "temp_sample.h"
#include "Product.h"
#include "ErrorLog.h"
#include "ieee_1547.h"
#include "freq_prot.h"
#include "fan_control.h"
#include "./OverUnderX/OverUnderX.h"
#include "rated_limit.h"
#include "modbus/modbus_manager.h"
#include "tftpServer/tftp_server.h"
#include "pulse_operate.h"
#include "logTimer.h"
#include "table_refresh.h"
#include "electricity_quantity_statistics.h"
#include "test.h"
#include "debug.h"
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include "misc.h"


#define THREAD_TABLE \
    X_MACRO(init_modbus_manager) \
    X_MACRO(tftpServerThread) \
    X_MACRO(logTimer_Thread) \
    X_MACRO(Product_Thread) \
    X_MACRO(WaveformSample_Thread) \
    X_MACRO(Errorlog_Thread) \
    X_MACRO(electricityQuantityStatisticsThread) \
    X_MACRO(FanControl_Thread) \
    X_MACRO(OverUnderX_Thread) \
    X_MACRO(RatedLimit_Thread) \
    X_MACRO(PulseOperate_Thread) \
    X_MACRO(TempSample_Thread) \
   // X_MACRO(TableRefresh_Thread) \
    X_MACRO(TableRefreshAssist_Thread) \
    X_MACRO(CommMonitor_Thread) \
    X_MACRO(Ieee1547_Thread) \
    // X_MACRO(Test_Thread) 


static struct threadInfo_s
{
    pthread_t tid;
    void *(*pFunc)(void *);
    const char *threadName;
} threadInfo[] = 
{
#define X_MACRO(funcName) {.pFunc = (void *)funcName, .threadName = #funcName},
    THREAD_TABLE
#undef X_MACRO 
};


int AllThread_CreateThread(void)
{
    Misc_InitThread(__func__);
    int idx = 0;

    for(idx = 0; idx < sizeof(threadInfo) / sizeof(struct threadInfo_s); idx++)
    {
        if((pthread_create(&threadInfo[idx].tid, NULL, threadInfo[idx].pFunc, NULL)) == -1)
        {
            PRINT_ERROR("Create Thread: %s failed!\n", threadInfo[idx].threadName);
            return -1;
        }
    }

    for(idx = 0; idx < sizeof(threadInfo) / sizeof(struct threadInfo_s); idx++)
    {
        if(pthread_join(threadInfo[idx].tid, NULL))
        {
            PRINT_ERROR("Join Thread: %s failed!\n", threadInfo[idx].threadName);
            return -1;
        }
    }

    return 0;
}


int AllThread_CancleThread(void)
{
    int idx = 0;

    for(idx = 0; idx < sizeof(threadInfo) / sizeof(struct threadInfo_s); idx++)
    {
        if((pthread_cancel(threadInfo[idx].tid)) == -1)
        {
            PRINT_ERROR("Cancel Thread: %s failed!\n", threadInfo[idx].threadName);
            return -1;
        }
    }

    return 0;
}

